#include "stdafx.h"
#include "DataServer.h"
//---
DataServer::DataServer(void)
{
	SetAutoDestroy(false);
	LOGGER_SET_FILE_PREFIX("DataServer");
	m_nTimerUnloadCharInfo = CreateTimer(boost::bind(&DataServer::onTimerUnloadCharInfo, this,_1),60*60*1000,TimerManager::TIMER_INFINITE);
}

DataServer::~DataServer(void)
{
}

void DataServer::onTimerUnloadCharInfo(UInt32 nTimerId)
{
	singleton<CharManager>::instance().unloadInvalidCharInfo();
}

std::string DataServer::GetServerPath()
{
	std::string strPath;
	char path[280] = { 0 };
	Int32 len = 0;

#ifdef _WIN32
	len = ::GetModuleFileNameA(0, path, MAX_PATH);
#else
	FILE* stream = fopen("/proc/self/cmdline", "r");
	fgets(path, 280, stream);
	fclose(stream);
	len = strlen(path);

	std::cout << "server path:" << path << std::endl;
#endif

	if(len > 0)
	{
		while(len > 0 && path[len] != '\\')
			len--;

		if(path[len] == '\\')
			path[len + 1] = 0;

		strPath.assign(path, len + 1);
	}
	return strPath;
}

sql::Connection* DataServer::GetConnection()
{
	try
	{
		sql::Connection* pConnection = get_driver_instance()->connect(m_strHost, m_strUsername, m_strPassword);
		pConnection->setSchema(m_strSchema);
		return pConnection;
	}
	catch(sql::SQLException& e)
	{
		 
		LOGGER_ERROR("SQL Exception:%s",e.what());
		LOGGER_ERROR("hostname::%s,database::%s,username::%s,password::%s,",m_strHost.c_str(),m_strSchema.c_str(),m_strUsername.c_str(),m_strPassword.c_str());
		throw e;
	}
};
sql::Connection* DataServer::GetConnectionAccount()
{
	try
	{
		sql::Connection* pConnection = get_driver_instance()->connect(m_strHostAccount, m_strUsernameAccount, m_strPasswordAccount);
		pConnection->setSchema(m_strSchemaAccount);
		return pConnection;
	}
	catch(sql::SQLException& e)
	{

		LOGGER_ERROR("SQL Exception:%s",e.what());
		LOGGER_ERROR("hostname::%s,database::%s,username::%s,password::%s,",m_strHostAccount.c_str(),m_strSchemaAccount.c_str(),m_strUsernameAccount.c_str(),m_strPasswordAccount.c_str());
		throw e;
	}
};

void DataServer::SetDatabaseConfig(const char* host, const char* schema, const char* username, const char* password)
{
	m_strHost = host;
	m_strSchema = schema;
	m_strUsername = username;
	m_strPassword = password;
}
void DataServer::SetDatabaseConfigAccount(const char* host, const char* schema, const char* username, const char* password)
{
	m_strHostAccount = host;
	m_strSchemaAccount = schema;
	m_strUsernameAccount = username;
	m_strPasswordAccount = password;
}

Int32 DataServer::Run()
{
	std::string path = GetServerPath();
	std::string filename = path + "DataServer.ini";

#ifndef _WIN32
	filename = "./DataServer.ini";
#endif

	if(singleton<Config>::instance().LoadFromFile(filename.c_str()) == false)
	{
		std::cout << "config file->DataServer.ini not found!" << std::endl;
		return -1;
	}

	std::string host = singleton<Config>::instance().GetItem("db-host");
	std::string schema = singleton<Config>::instance().GetItem("db-schema");
	std::string username = singleton<Config>::instance().GetItem("db-username");
	std::string password = singleton<Config>::instance().GetItem("db-password");
	LOGGER_INFO("game server,host:%s,schema:%s,username:%s,password:%s ",host.c_str(), schema.c_str(), username.c_str(), password.c_str());

	SetDatabaseConfig(host.c_str(), schema.c_str(), username.c_str(), password.c_str());

	host = singleton<Config>::instance().GetItem("db-host-account");
	schema = singleton<Config>::instance().GetItem("db-schema-account");
	username = singleton<Config>::instance().GetItem("db-username-account");
	password = singleton<Config>::instance().GetItem("db-password-account");
	LOGGER_INFO("account server,host:%s,schema:%s,username:%s,password:%s ",host.c_str(), schema.c_str(), username.c_str(), password.c_str());

	SetDatabaseConfigAccount(host.c_str(), schema.c_str(), username.c_str(), password.c_str());

	ISocketServer* pSocketServer = CreateSocketServer();
	if(pSocketServer == NULL)
	{
		LOGGER_INFO("pSocketServer == NULL");
		return 0;
	}
	singleton<ServerCallbackData>::instance().SetSocketServer(pSocketServer);

	std::string strDataIp = singleton<Config>::instance().GetItem("data-ip");
	std::string strDataPort = singleton<Config>::instance().GetItem("data-port");
	LOGGER_INFO("data server,ip:%s,port:%s ",strDataIp.c_str(),strDataPort.c_str());
	pSocketServer->Run(strDataIp.c_str(),strDataPort.c_str(),&(singleton<ServerCallbackData>::instance()));
	
	/*try 
	{
		sql::Driver * driver = get_driver_instance();
		std::auto_ptr< sql::Peer > con(driver->connect(m_strHost, m_strUsername, m_strPassword));

		std::auto_ptr< sql::Statement > stmt(con->createStatement());
		stmt->execute("USE " + m_strSchema);
		stmt->execute("DROP TABLE IF EXISTS test");
		stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
	} 
	catch (sql::SQLException &e) 
	{
		LOGGER_ERROR("SQLException:%s",e.what());
		return EXIT_FAILURE;
	}
	catch (std::runtime_error &e) 
	{
		LOGGER_ERROR("SQLException:%s",e.what());
		return EXIT_FAILURE;
	}*/

	singleton<ModulePlayer>::instance().Register();
	while(1)
	{
		singleton<TimerManager>::instance().Update();
		pSocketServer->Update();
		_Sleep(1);
	}
}


int main(int argc, char* argv[])
{
	char* locname = setlocale(LC_ALL, ""); 
	LOGGER_INFO("Current locale is: %s", locname);
	locname = setlocale(LC_ALL, LC_NAME_zh_CN_UTF8); 
	if ( NULL == locname ) 
	{ 
		LOGGER_INFO("setlocale() with %s failed.", LC_NAME_zh_CN_UTF8); 
		char* locname = setlocale(LC_ALL, ""); 
		LOGGER_INFO("Current locale is: %s", locname);
	} 
	else 
	{ 
		LOGGER_INFO("setlocale() with %s succeed.", LC_NAME_zh_CN_UTF8); 
	} 

	LOGGER_SET_FILE_PREFIX("DataServer");
	singleton<DataServer>::instance().Run();
	return 0;
}